{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "解决 MNIST 问题  \n",
    "本程序定义前向传播过程及神经网络中的参数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 定义神经网络结构相关的参数\n",
    "INPUT_NODE = 784\n",
    "OUTPUT_NODE = 10\n",
    "LAYER1_NODE = 500"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#通过tf.get_variable函数获取变量。在训练神经网络时会创建这些变量：在测试时会通过保存的模型加载这些变量的取值。\n",
    "#而且更加方便的是，因为可以在变量加载时将滑动平均变量重命名，所以可以直接通过同样的名字在训练时使用变量自身，\n",
    "#而在测试时使用变量的滑动平均值。在这个函数中也会将变量的正则化损失加入损失集合。\n",
    "def get_weight_variable(shape,regularizer):\n",
    "    weights = tf.get_variable(\"weights\",shape,initializer=tf.truncated_normal_initializer(stddev=0.1))\n",
    "    #当给出了正则化生成函数时，将当前变量的正则化损失加入名字为losses的集合。在这里使用了add_to_collection函数\n",
    "    #将一个张量加入一个集合，而这个集合的名称为losses。这是自定义的集合，不在TensorFlow 自定管理的集合列表中\n",
    "    if regularizer != None:\n",
    "        tf.add_to_collection('losses',regularizer(weights))\n",
    "    return weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#定义神经网络前向传播过程。\n",
    "def inference(input_tensor,regularizer):\n",
    "    #声明第一层神经网络的变量并完成前向传播过程。\n",
    "    with tf.variable_scope('layer1'):\n",
    "        #这里通过tf.get_variable 或 tf.Varibale 没有本质区别，因为在训练或测试中没有在同一个程序中多次调用这个函数。\n",
    "        #如果在同一个程序中多次调用，在第一次调用之后需要将resuse 参数设置为True。\n",
    "        weights = get_weight_variable([INPUT_NODE,LAYER1_NODE],regularizer)\n",
    "        biases = tf.get_variable(\"biases\",[LAYER1_NODE],initializer=tf.constant_initializer(0.0))\n",
    "        layer1 = tf.nn.relu(tf.matmul(input_tensor,weights) + biases)\n",
    "    #类似的声明第二层神经网络的变量并完成前向传播过程\n",
    "    with tf.variable_scope('layer2'):\n",
    "        weights = get_weight_variable([LAYER1_NODE,OUTPUT_NODE],regularizer)\n",
    "        biases = tf.get_variable('biases',[OUTPUT_NODE],initializer=tf.constant_initializer(0.0))\n",
    "        layer2 = tf.matmul(layer1,weights) + biases\n",
    "    #返回最后的前向传播的结果\n",
    "    return layer2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
